﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MultiDAQ_Analysis.Calculation.Interfaces;
using MultiDAQ_Analysis.Calculation.Results;
using MultiDAQ_Analysis.Util;

namespace MultiDAQ_Analysis.Calculation.Calculators
{
    public abstract class BaseMeasurementCalculator : IMeasurementCalculator
    {
        public abstract string MeasurementType { get; }
        public abstract Type ParameterType { get; }

        public virtual bool CanCalculate(MeasurementCalculationContext context)
        {
            return context?.RawData != null && context.RawData.Count > 0;
        }

        public async Task<MeasurementCalculationResult> CalculateAsync(MeasurementCalculationContext context)
        {
            var result = new MeasurementCalculationResult
            {
                MeasurementType = MeasurementType,
                IsFinalResult = context.CurrentRound >= context.TotalRounds
            };

            try
            {
                if (!ValidateContext(context))
                {
                    result.IsSuccess = false;
                    result.ErrorMessage = "计算上下文验证失败";
                    return result;
                }

                await ProcessSingleRound(context, result);

                if (result.IsFinalResult)
                {
                    await ProcessFinalCalculation(context, result);
                }

                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMessage = ex.Message;
                Console.WriteLine($"[计算错误] {MeasurementType}: {ex.Message}");
            }

            return result;
        }

        public async Task SaveResultsAsync(MeasurementCalculationResult result)
        {
            if (!result.IsSuccess || !result.IsFinalResult) return;

            foreach (var channelResult in result.ChannelResults)
            {
                try
                {
                    await SaveChannelResult(channelResult.Key, channelResult.Value, result);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"[保存错误] {MeasurementType} 通道 {channelResult.Key + 1}: {ex.Message}");
                }
            }
        }

        protected abstract Task ProcessSingleRound(MeasurementCalculationContext context, MeasurementCalculationResult result);
        protected abstract Task ProcessFinalCalculation(MeasurementCalculationContext context, MeasurementCalculationResult result);
        protected abstract Task SaveChannelResult(int channelIndex, ChannelCalculationResult channelResult, MeasurementCalculationResult overallResult);

        protected virtual bool ValidateContext(MeasurementCalculationContext context)
        {
            return context?.RawData != null && context.RawData.Count > 0;
        }

        protected double CalculateAverage(List<double> values)
        {
            return values.Count > 0 ? values.Average() : 0;
        }

        protected double CalculateStandardDeviation(List<double> values)
        {
            if (values.Count <= 1) return 0;
            double mean = values.Average();
            double sumOfSquaredDifferences = values.Sum(val => (val - mean) * (val - mean));
            return Math.Sqrt(sumOfSquaredDifferences / (values.Count - 1));
        }

        protected (double alpha, double beta) GetBackgroundData(int channelIndex)
        {
            try
            {
                var channelData = ChannelDataManager.LoadChannelData(channelIndex);
                return (channelData.WorkConditions.AlphaBackground, channelData.WorkConditions.BetaBackground);
            }
            catch
            {
                return (0, 0);
            }
        }
    }
}